module shader.environment;

import canvas.abstractcanvas;
import std.math;
import std.stdio;
import std.c.stdio;
import utils.color;
import utils.vector2;
import utils.vector3;

class Environment {
    private AbstractCanvas mTexture;
    private RGBColor mColor;
    private float mMinPhi = float.min;

    this() {
        mColor = RGBColor(0.6f,0.6f,1.0f);
    }

    public RGBColor getColor(Vector3f pos) {
        if (mTexture) {
            float r = (M_1_PI)*acos(pos.z)/sqrt(pos.x*pos.x + pos.y*pos.y);
            Vector2i ptex = Vector2i(
                cast(int)(((r*pos.x)/2.0f+0.5f)*(mTexture.width)),
                cast(int)(((-r*pos.y)/2.0f+0.5f)*(mTexture.height)));
            if (ptex.x >= mTexture.width)
                ptex.x = mTexture.width-1;
            if (ptex.y >= mTexture.height)
                ptex.y = mTexture.height-1;
            if (ptex.x < 0)
                ptex.x = 0;
            if (ptex.y < 0)
                ptex.y = 0;
            return mTexture.getPixelColor(ptex);
        } else {
            return getColor(acos(pos.y),atan2(pos.z,pos.x));
        }
    }

    public RGBColor getColor(float theta, float phi) {
        if (mTexture) {
            Vector3f pos = Vector3f.fromSpherical(theta,phi,1.0f);
            return getColor(pos);
            //return mTexture.getPixelColor(Vector2i(
            //    cast(int)((sin(theta)*cos(phi/2.0f+PI_2)/2.0f+0.5f)*mTexture.width),
            //    cast(int)((-cos(theta)/2.0f+0.5f)*mTexture.height)
            //    ));
        } else {
            return mColor*((1.0f+2.0f*fmax(0,cos(theta)))/3.0f);
        }
    }

    public void texture(AbstractCanvas tex) {
        mTexture = tex;
    }
    public AbstractCanvas texture() {
        return mTexture;
    }

    public void color(RGBColor col) {
        mColor = col;
    }
}
